package ants;

import java.io.IOException;

import strategies.DiffusionStrategyWithFunctionalWeighting;

import com.google.common.collect.ImmutableList;

/**
 * Processes one turn. Handles all I/O.
 * 
 */
public class TurnManager {
  
  private static final char   COMMENT_CHAR = '#';
  
  public static final String  GO           = "go";
  
  private static final String READY        = "ready";
  
  
  private static boolean isEndOfLineChar(char c) {
    return c == '\r' || c == '\n';
  }
  
  
  private static boolean isEndOfTurnLine(String line) {
    return line.equals(READY) || line.equals(GO);
  }
  
  
  /**
   * The first time through, read the game constants. Subsequent times through,
   * play a turn.
   * 
   * @param prevGameState
   *          the game state as left by the previous turn -- or a blank game
   *          state initially
   * @throws IOException
   * @throws TimeRunningOutException
   */
  public static void playRemainingTurns(GameState prevGameState)
                                                                throws IOException {
    
    final ImmutableList<String> turnInput = readLines(new ImmutableList.Builder<String>( ), readAChar( )).build( );
    final String line = turnInput.get(turnInput.size( ) - 1);
    
    final GameState gameState = line.equals(READY) ? prevGameState : new GameState(prevGameState, turnInput);
    
    if (line.equals(READY)) GameState.setGameConstants(turnInput);
    
    // To get the turnCount right, wait until after updating the gameState to
    // print the input.
    //for (final String inputLine: turnInput)
      //Logger.log("-> " + inputLine);
    
//     Logger.log("TurnManager.gameState: " + gameState);
    
    if (line.equals(GO)) new DiffusionStrategyWithFunctionalWeighting(gameState).doTurn( );
    
    gameState.print(GO);
    
    playRemainingTurns(gameState);
  }
  
  
  private static char readAChar( ) throws IOException {
    return (char) System.in.read( );
  }
  
  
  private static String readALine(char c) throws IOException {
    return c == 0 || isEndOfLineChar(c) ? "" : c + readALine(readAChar( ));
  }
  
  
  private static ImmutableList.Builder<String> readLines(ImmutableList.Builder<String> builder,
                                                         char c)
                                                                throws IOException {
    final String line = removeComment(readALine(c).toLowerCase( )).trim( );
    builder.add(line);
    return isEndOfTurnLine(line) ? builder : readLines(builder, readAChar( ));
  }
  
  
  private static String removeComment(String line) {
    final int commentCharIndex = line.indexOf(COMMENT_CHAR);
    return commentCharIndex >= 0 ? line.substring(0, commentCharIndex)
                                : line;
  }
  
  
}
